#include<iostream>
#include<vector>
#include<string>
#include<time.h>
#include<chrono>
#include<functional>
#include<windows.h>

using namespace std;
using func_int_t = function<void(int, int, int, int)>;
using func_short_int_t = function<void(int, int)>;
using func_t = function<void()>;
using func_bool_t = function<bool(int, int)>;

#define KEY_PRESS(VK) ((GetAsyncKeyState(VK)&0x1) ? 1 : 0)

// 扫雷难度划分为三级: 简单, 中等, 困难

// 简单
#define EASY_ROW 9
#define EASY_COL 9
#define EASY_MINE 10


// 中等 
#define MEDIUM_ROW 16
#define MEDIUM_COL 16
#define MEDIUM_MINE 40

// 困难
#define HARD_ROW 16
#define HARD_COL 30
#define HARD_MINE 99

struct difficulty {
	int row;
	int col;
	int mine;
};

vector<difficulty> diff({ {EASY_ROW, EASY_ROW, EASY_MINE},
							  {MEDIUM_ROW, MEDIUM_COL, MEDIUM_MINE},
							  {HARD_ROW, HARD_COL, HARD_MINE} }); // 三种难度的基本设置


wchar_t Blank = L'□';
wchar_t Empty = L'  ';
wchar_t Mine = L'※';
vector<wchar_t> DefaultImage({ Blank, Empty, Mine }); // 三种图案

// 用于对游戏界面的设置

// 方案
// 1. 可以用上，下，左，右来控制光标位置，Enter来表示排查当前位置，F表示标记？ 
// 2. 直接在终端上输入想要排查的坐标位置?

// 可设计为单例模式，避免其他类的重新构造
class SystemOperation
{
public:
	SystemOperation() :_hConsole(GetStdHandle(STD_OUTPUT_HANDLE))
	{
		_setpos = [&](short x, short y) {
			COORD pos = { x, y };

			SetConsoleCursorPosition(_hConsole, pos);
			};

		_pause_cls = [&](int x, int y) {
			_setpos(x, y);
			system("pause");
			system("cls");
			};

		_clear_area = [&](int x, int y, int width, int height) {
			COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
			DWORD charsWritten;

			// 循环清除每一行
			for (int i = 0; i < height; i++)
			{
				FillConsoleOutputCharacter(_hConsole, ' ', width, coord, &charsWritten);
				coord.Y++;  // 移动到下一行
			}

			};

		_cursor_invisible = [&]() {
			if (_hConsole == INVALID_HANDLE_VALUE)  return false;

			CONSOLE_CURSOR_INFO CursorInfo;
			GetConsoleCursorInfo(_hConsole, &CursorInfo);
			CursorInfo.bVisible = false;
			SetConsoleCursorInfo(_hConsole, &CursorInfo);
			};


		_set_consol_size = [](int cols, int lines) {
			string command = "mode con cols=" + to_string(cols) + " lines=" + to_string(lines);
			system(command.c_str());
			system("title 扫雷");
			};


		_is_char_at_pos = [&](int x, int y) {
			if (_hConsole == INVALID_HANDLE_VALUE)  return false;

			// 设置要检查的坐标
			COORD pos = { static_cast<SHORT>(x), static_cast<SHORT>(y) };

			// 读取字符
			TCHAR ch;
			DWORD charsRead;
			if (!ReadConsoleOutputCharacter(_hConsole, &ch, 1, pos, &charsRead)) return false;

			// 检查是否为空格或空字符
			return (ch != ' ' && ch != '\0' && ch != '\t');
			};

		_clear_whole_screen = [&](int x, int y) {

			for (int i = 0; i < y; i++)
				_clear_area(0, i, x, 1);

			_setpos(0, 0);
			};
	}

	//SystemOperation* self = static_cast<SystemOperation*>();


	~SystemOperation() {}

	HANDLE _hConsole;
	func_short_int_t _setpos;
	func_short_int_t _pause_cls;
	func_int_t _clear_area;
	func_t _cursor_invisible;
	func_short_int_t _set_consol_size;
	func_bool_t _is_char_at_pos;
	func_short_int_t _clear_whole_screen;
};

static SystemOperation _oper;

class Error
{
public:
	static void ErrorInput(int x, int y, string str = "输入的序号不在范围之内,请重新输入")
	{
		_oper._setpos(x, y);
		cout << str;
		Sleep(2000);
	}

	static void ErrorTranslate(string str, int x, int y)
	{
		try {
			int tmp = stoi(str);
		}
		catch (const invalid_argument& e) {
			_oper._setpos(x, y);
			cerr << "错误:无效参数(无法转换为数字)" << endl;
		}
		catch (const out_of_range& e) {
			_oper._setpos(x, y);
			cerr << "错误:数值超出 int 范围" << endl;
		}
	}

};

namespace GameSet
{
	class Set
	{
	public:
		Set()
		{
		}

		void GameStart()
		{
			_oper._set_consol_size(120, 35);
			_oper._cursor_invisible();

			WelcomeToGame();
			SelectImage();
			Menu();
		}

		void WelcomeToGame()
		{
			_oper._setpos(50, 14);
			cout << "欢迎来到扫雷游戏";
			_oper._pause_cls(50, 29);

			_oper._setpos(42, 13);
			cout << "这是一款输入坐标来排查位置的扫雷游戏" << endl;
			_oper._setpos(38, 14);
			cout << "通过输入您想要排查的坐标位置来进行每一步操作" << endl;
			_oper._pause_cls(50, 29);
		}

		void Func(int x, int y, string message)
		{
			_oper._setpos(x, y);
			cout << message << endl;
		}

		string& Input(string& input, int x = 0, int y = 0)
		{
			while (1)
			{
				if (KEY_PRESS('0')) cout << 0, input += '0';
				else if (KEY_PRESS('1')) cout << 1, input += '1';
				else if (KEY_PRESS('2')) cout << 2, input += '2';
				else if (KEY_PRESS('3')) cout << 3, input += '3';
				else if (KEY_PRESS('4')) cout << 4, input += '4';
				else if (KEY_PRESS('5')) cout << 5, input += '5';
				else if (KEY_PRESS('6')) cout << 6, input += '6';
				else if (KEY_PRESS('7')) cout << 7, input += '7';
				else if (KEY_PRESS('8')) cout << 8, input += '8';
				else if (KEY_PRESS('9')) cout << 9, input += '9';

				else if (KEY_PRESS(VK_BACK))
				{
					if (!input.empty())
					{
						int pos = x + input.size();
						_oper._clear_area(pos - 1, y, 1, 1);
						input.pop_back();
						_oper._setpos(pos - 1, y);
					}
				}

				else if (KEY_PRESS(VK_RETURN))
				{
					if (!input.empty()) break;
					else input += '0';
				}
			}

			return input;
		}

		void ImageOption(int index)
		{
			vector<wchar_t> image({ L'♀', L'♂', L'∷', L'※', L'■', L'★', L'●', L'◆', L'◎', L'¤',
									L'↑', L'$', L'€', L'℃', L'§', L'@', L'±', L'×', L'÷', L'&' });
			// option
			{
				Func(5, 7, "1. ♀ 女");
				Func(5, 9, "2. ♂ 男");
				Func(5, 11, "3. ∷ 四点");
				Func(5, 13, "4. ※ 星");
				Func(5, 15, "5. ■ 方块");
				Func(5, 17, "6. ★ 五角星");
				Func(5, 19, "7. ● 圆形");
				Func(5, 21, "8. ◆ 菱形");
				Func(5, 23, "9. ◎ 同心圆");
				Func(5, 25, "10. ¤ 货币标记");

				Func(40, 7, "11. ↑ 上箭头");
				Func(40, 9, "12. $ 美刀");
				Func(40, 11, "13. € 欧元");
				Func(40, 13, "14. ℃  摄氏度");
				Func(40, 15, "15. § 小结");
				Func(40, 17, "16. @ 邮件符号");
				Func(40, 19, "17. ± 正负号");
				Func(40, 21, "18. × 乘法");
				Func(40, 23, "19. ÷ 除法");
				Func(40, 25, "20. & 与");
			}

			_oper._setpos(63, 25);
			cout << "(只按Enter以保持默认)" << endl;
			_oper._setpos(60, 26);
			cout << "请输入你想要的图案编号(按下Enter以确定选择): ";
		again:
			// 清除上次的输入
			_oper._clear_area(105, 26, 4, 1);
			_oper._clear_area(0, 27, 120, 1);
			_oper._clear_area(0, 28, 120, 1);

			string str;
			_oper._setpos(105, 26);
			str = Input(str, 105, 26);

			Error::ErrorTranslate(str, 60, 26);

			int num = stoi(str);
			if (num != 0)
			{
				if (num > 0 && num <= 20) DefaultImage[index] = image[num - 1];
				else
				{
					Error::ErrorInput(60, 26);
					goto again;
				}
			}

			_oper._pause_cls(50, 29);
		}

		void SelectImage()
		{
			// 选择页面介绍
			{
				_oper._setpos(50, 12);
				cout << "在接下来的页面里" << endl;
				_oper._setpos(39, 13);
				cout << "您可以选择喜欢的图案来DIY属于自己的扫雷" << endl;
				_oper._setpos(28, 14);
				cout << "虽然选择是多样化的，但还是不建议您选择重复图案，以免影响游戏体验" << endl;
				_oper._pause_cls(50, 29);
			}

			// 对未排查区域的图案选择
			{
				_oper._setpos(5, 5);
				cout << "这里是对‘未被排查’区域图案的选择, 默认为'□'" << endl;
				ImageOption(0);
			}

			// 对空白区域的图案选择
			{
				_oper._setpos(5, 5);
				cout << "这里是对‘空白’区域图案的选择, 默认为' '" << endl;
				ImageOption(1);
			}

			// 对地雷图案的选择
			{
				_oper._setpos(5, 5);
				cout << "这里是对‘地雷’图案的选择, 默认为'※'" << endl;
				ImageOption(2);
			}
		}

		void Menu()
		{
			_oper._set_consol_size(120, 35);
			Func(50, 8, "游戏难度选择");

			Func(43, 11, "1. 简单难度 ( 9X9 , mine = 10)");
			Func(43, 14, "2. 中等难度 (16X16, mine = 40)");
			Func(43, 17, "3. 困难难度 (16X30, mine = 99)");


		again:_oper._clear_area(80, 22, 4, 1);
			_oper._clear_area(41, 23, 33, 1);
			_oper._setpos(39, 22);

			string str;
			cout << "请输入您想游玩的难度(按下Enter以确定选择): ";
			str = Input(str, 39 + sizeof("请输入您想游玩的难度(按下Enter以确定选择): ") - 1, 22);
			Error::ErrorTranslate(str, 41, 23);

			int num = stoi(str);
			if (num < 1 || num > 3)
			{
				Error::ErrorInput(41, 23);
				goto again;
			}

			else
			{
				_choose_row = diff[num - 1].row;
				_choose_col = diff[num - 1].col;
				_choose_mine = diff[num - 1].mine;
			}

			_oper._pause_cls(50, 29);
		}

		int GetRow() { return _choose_row; }

		int GetCol() { return _choose_col; }

		int GetMine() { return _choose_mine; }

		~Set() {}

	private:
		/*func_short_t _setpos;
		func_t _pause_cls;
		func_int_t _clear_area;*/

		SystemOperation _oper;

		int _choose_row = 0;
		int _choose_col = 0;
		int _choose_mine = 0;
	};
}


// 地图设置
// ∂♛☆ᶞ⊙➺➬➣♤♧
// ♠♥♦♣☼☽♀☺◐☑☹♂◑☒☀☾
// ※♈♉♊♋♌♎♏♐♑♓♒♍☯
//★○●◇◆□■

// 棋盘初始化
namespace Board
{
	class SetBoard
	{
	public:
		SetBoard(int row, int col, int count)
			: _row(row), _col(col), _count(count)
			, _blank(DefaultImage[0]), _empty(DefaultImage[1]), _landmine(DefaultImage[2])
		{
			_cnt = _row * _col - _count;
			_board.resize(row + 1, vector<wchar_t>(col + 1, _blank));
			_mine.resize(row + 1, vector<wchar_t>(col + 1, _empty));

			int tmp = 0;

			for (int i = 0; i <= _row; i++)
				_board[i][0] = (char)('0' + tmp++);

			tmp = 0;
			for (int j = 0; j <= _col; j++)
				_board[0][j] = (char)('0' + tmp++);
		}

		// 打印初始化棋盘
		void PrintBoard(int background = 0)
		{
			for (int i = 0; i <= _row; i++)
			{
				// 列号前的空格
				int tmp = background;
				if (!i) tmp = 0;
				while (tmp)
				{
					tmp--;
					cout << " ";
				}


				for (int j = 0; j <= _col; j++)
				{
					if (i && j)
					{
						if (_board[i][j] == ' ' || _board[i][j] == 'X' || (_board[i][j] <= '9' && _board[i][j] >= '1')) cout << " ";
						wprintf(L"%3c", _board[i][j]);
					}

					else
					{
						if (i == 0)
						{
							if ((int)(_board[i][j] - '0') < 9)
							{
								if (_blank == L'$' || _blank == L'&' || _blank == L'@') cout << (int)(_board[i][j] - '0') << "  ";
								else cout << (int)(_board[i][j] - '0') << "   ";
							}
							else cout << (int)(_board[i][j] - '0') << "  ";
						}
						else printf("%3d", _board[i][j] - '0');
					}

				}
				cout << endl;
			}
			cout << endl;
		}

		// 布雷 -- 5.10(BUG--AC)
		void SetMine(int i = -1, int j = -1)
		{
			int count = _count;
			while (count)
			{
				int x = rand() % _row + 1;
				int y = rand() % _col + 1;
				if (x > 0 && x <= _row && y > 0 && y <= _col
					&& x != i && x != i + 1 && x != i - 1
					&& y != j && y != j + 1 && y != j - 1
					&& _mine[x][y] == _empty)
				{
					_mine[x][y] = _landmine;
					count--;
				}
			}
		}

		// Only Test
		void PrintMine()
		{
			// 打印第一行行号
			{
				cout << "  ";
				for (int i = 0; i <= _col; i++)
				{
					if (i < 9) cout << i << "   ";
					else cout << i << "  ";
				}
				cout << endl;
			}

			for (int i = 0; i < _row; i++)
			{
				//cout << "  " << i + 1;
				printf("%3d", i + 1);
				for (int j = 1; j <= _col; j++)
				{
					wprintf(L"%3c", _mine[i + 1][j]);
				}
				cout << endl;
			}

			cout << endl;
		}

		void ChangeSpecifidPos(int i, int j, wchar_t you_want) { _board[i][j] = you_want; }

		wchar_t CheckBoard(int i, int j) { return _board[i][j]; }

		wchar_t CheckMine(int i, int j) { return _mine[i][j]; }

		int GetCnt() { return _cnt; }

		wchar_t GetBlank() { return _blank; }

		wchar_t GetEmpty() { return _empty; }

		wchar_t GetMine() { return _landmine; }

		vector<vector<wchar_t>> GetBoard() { return _board; }

		vector<vector<wchar_t>> GetMineBoard() { return _mine; }

		// 空白展开

		// 'M' -- mine, 'E' -- blank, 'B' -- empty
		//vector<wchar_t> DefaultImage({ Blank, Empty, Mine }); // 三种图案


		void UpdateBoard(int i, int j)
		{
			// 直接点击到雷的逻辑在函数外部已有
			Dfs(i, j);
		}

		void FailShowMine(int flag)
		{
			for (int i = 1; i <= _row; i++)
				for (int j = 1; j <= _col; j++)
					if (_board[i][j] == _blank && _mine[i][j] == _landmine)
						_board[i][j] = _landmine;

			PrintBoard(flag);
		}

		bool Check() { return CheckIsWin(); }

		~SetBoard() {}
	private:
		int dx[8] = { -1, -1, -1, 0, 0, 1, 1, 1 };
		int dy[8] = { -1, 0, 1, -1, 1, -1, 0, 1 };

		void Dfs(int i, int j)
		{
			int count = 0;
			for (int k = 0; k < 8; k++)
			{
				int x = i + dx[k], y = j + dy[k];
				if (x >= 1 && x <= _row && y >= 1 && y <= _col
					&& _mine[x][y] == DefaultImage[2])
				{
					count++;
				}
			}

			if (count)
			{
				_board[i][j] = (char)(count + '0');
				return;
			}

			else
			{
				_board[i][j] = DefaultImage[1];
				for (int k = 0; k < 8; k++)
				{
					int x = i + dx[k], y = j + dy[k];
					if (x >= 1 && x <= _row && y >= 1 && y <= _col
						&& _board[x][y] == DefaultImage[0])
					{
						_board[x][y] = DefaultImage[1];
						Dfs(x, y);
					}
				}
			}
		}

		bool CheckIsWin()
		{
			int cnt = _cnt;
			for (int i = 1; i <= _row; i++)
			{
				for (int j = 1; j <= _col; j++)
				{
					if (_board[i][j] != _blank)
						cnt--;
				}
			}

			return cnt == 0;
		}

	private:
		int _row;
		int _col;
		int _count;
		int _cnt;

		wchar_t _blank;
		wchar_t _empty;
		wchar_t _landmine;

		SystemOperation _oper;

		// 下标范围都是 1 ~ _row/_col
		vector<vector<wchar_t>> _board;
		vector<vector<wchar_t>> _mine;
	};
}

// 游戏界面

namespace GamePlay
{
	enum State
	{
		Run,
		Lose,
		Win
	};

	class Game
	{
	private:
		string ButtonOneCheck(string input, int x = 0, int y = 0, string previous = "")
		{
			while (1)
			{
				if (KEY_PRESS('0')) cout << 0, input += '0';
				else if (KEY_PRESS('1')) cout << 1, input += '1';
				else if (KEY_PRESS('2')) cout << 2, input += '2';
				else if (KEY_PRESS('3')) cout << 3, input += '3';
				else if (KEY_PRESS('4')) cout << 4, input += '4';
				else if (KEY_PRESS('5')) cout << 5, input += '5';
				else if (KEY_PRESS('6')) cout << 6, input += '6';
				else if (KEY_PRESS('7')) cout << 7, input += '7';
				else if (KEY_PRESS('8')) cout << 8, input += '8';
				else if (KEY_PRESS('9')) cout << 9, input += '9';
				else if (KEY_PRESS(VK_BACK))
				{
					if (!input.empty())
					{
						// 计算当前位置,还得考虑前一个字符串输入(28,17)
						if (previous.empty())
						{
							int pos = x + input.size();
							_oper._clear_area(pos - 1, y, 1, 1);
							input.pop_back();
							_oper._setpos(pos - 1, y);
						}

						else
						{
							int pos = previous.size() + 1 + x + input.size();
							_oper._clear_area(pos - 1, y, 1, 1);
							input.pop_back();
							_oper._setpos(pos - 1, y);
						}
					}
				}

				else if (KEY_PRESS(VK_RETURN))
				{
					if (!input.empty() && !previous.empty())
						break;
				}

				else if (KEY_PRESS(VK_SPACE))
					if (!input.empty() && previous.empty())
					{
						cout << " ";
						break;
					}
			}

			return input;
		}

		vector<string> ButtonTwoCheck(string& str1, string& str2, int x, int y)
		{
			while (1)
			{
				str1 = ButtonOneCheck(str1, x, y);
				if (!str1.empty())
				{
					str2 = ButtonOneCheck(str2, x, y, str1);
					break;
				}
			}

			vector<string> ret({ str1, str2 });
			return ret;
		}

	public:
		GameSet::Set set;

		Game(int mine) :_game_state(Run)
		{
		try_again:
			int _mine = set.GetMine() == 0 ? mine : set.GetMine();
			vector<int> tmp({ 10, 40, 99 });
			_diff = mine == tmp[0] ? 1 : mine == tmp[1] ? 2 : mine == tmp[2] ? 3 : -1;

			Board::SetBoard board(diff[_diff - 1].row, diff[_diff - 1].col, diff[_diff - 1].mine);

			// 初始化各个难度的扫雷控制台面板大小
			if (_diff == 1)
			{
				_oper._set_consol_size(50, 24);
				int count = 0; // 检测按键次数

				// 游玩逻辑
				// 1. 首次点击会开出一篇区域，不会踩雷 
				//   -- 延迟生成雷区: 对第一次点击进行额外检测, 先将该位置赋值为'空白', 再生成雷区, 再dfs
				// 2. 点击后的地图会覆盖在原先的地图上(对vector board进行修改)
				// 3. 用户输入将是"num1 num2"形式, 采用按键检测还是string分段？
				// string会因为stoi()导致进行额外检测,但是按键检测需要考虑空格的隔断
				// 根据在选择图案页面的经验,采用按键检测逻辑

				while (_game_state == Run)
				{
					_oper._setpos(6, 4); board.PrintBoard(4);
				again:
					_oper._clear_area(0, 19, 50, 1);
					_oper._clear_area(28, 17, 22, 1);
					string x, y;
					_oper._setpos(7, 17); cout << "请输入想排查的坐标: ";
					_oper._setpos(6, 18); cout << "(输入空格隔段, 回车确认)";


					{
						_oper._setpos(28, 17);
						vector<string> index = ButtonTwoCheck(x, y, 28, 17);

						//对数字准确性检测
						Error::ErrorTranslate(index[0], 6, 19);

						int i = stoi(index[0]), j = stoi(index[1]);
						if (i >= 1 && i <= diff[_diff - 1].row && j >= 1 && j <= diff[_diff - 1].col)
						{
							// 为首次点击延迟布雷(Bug)
							if (count == 0)
							{
								count++;
								board.ChangeSpecifidPos(i, j, board.GetEmpty());
								board.SetMine(i, j);
								board.UpdateBoard(i, j);
							}

							else
							{
								// 判断点击位置在board上是否有效
								if (board.CheckBoard(i, j) == board.GetBlank())
								{
									// 判断位置的是否为雷
									if (board.CheckMine(i, j) == board.GetMine())
									{
										_game_state = Lose;

										_oper._clear_area(0, 17, 50, 1);
										_oper._clear_area(0, 18, 50, 1);

									lose_again:
										_oper._clear_area(43, 18, 7, 1);

										// 失败展示
										board.ChangeSpecifidPos(i, j, L'X');
										_oper._setpos(6, 4); board.FailShowMine(4);

										_oper._setpos(17, 17); cout << "很遗憾，您输了";
										_oper._setpos(4, 18); cout << "是否要再开始一局? --- (1. Yes  2. No): ";
										string is_restart;

										is_restart = ButtonOneCheck(is_restart, 4 + sizeof("是否要再开始一局? --- (1. Yes  2. No): ") - 1, 18, "Noob");
										Error::ErrorTranslate(index[0], 6, 18);

										int num = stoi(is_restart);
										if (num == 1)
										{
											// 跳转选择页面(清除当前页面)
											_oper._clear_whole_screen(50, 24);
											set.Menu();
											_game_state = Run;
											goto try_again;
										}

										else if (num == 2) break;

										else
										{
											Error::ErrorInput(6, 18);
											goto lose_again;
										}

									}

									else
									{
										// dfs (SetBoard完全封装，直接使用类成员调用函数对其进行修改(可以,但不好))
										board.UpdateBoard(i, j);
										if (board.Check())
										{
											// win
											_game_state = Win;

											_oper._clear_area(0, 17, 50, 1);
											_oper._clear_area(0, 18, 50, 1);

										win_again:
											_oper._clear_area(43, 18, 7, 1);

											_oper._setpos(17, 17); cout << "恭喜，您赢了"; // 加些其他的图案
											_oper._setpos(4, 18); cout << "是否要再开始一局? --- (1. Yes  2. No): ";
											string is_restart;

											is_restart = ButtonOneCheck(is_restart, 4 + sizeof("是否要再开始一局? --- (1. Yes  2. No): ") - 1, 18, "Guru");
											Error::ErrorTranslate(index[0], 6, 18);

											int num = stoi(is_restart);
											if (num == 1)
											{
												// 跳转选择页面
												_oper._clear_whole_screen(50, 24);
												set.Menu();
												_game_state = Run;
												goto try_again;
											}

											else if (num == 2) break;

											else
											{
												Error::ErrorInput(6, 18);
												goto win_again;
											}

											break;
										}
									}
								}

								// 点击的位置为数字或为‘空白’(Bug)
								else
								{
									Error::ErrorInput(6, 19, "输入坐标位置不可被排查, 请重新输入");
									goto again;
								}
							}
						}

						else
						{
							Error::ErrorInput(6, 19, "输入坐标不合法, 请重新输入");
							goto again;
						}
					}
				}
			}

			else if (_diff == 2)
			{
				_oper._set_consol_size(80, 30);
				int count = 0;

				while (_game_state == Run)
				{
					_oper._setpos(6, 4); board.PrintBoard(4);

					string x, y;


				}

				_oper._pause_cls(30, 28);
			}

			else if (_diff == 3)
			{
				_oper._set_consol_size(125, 40);
				_oper._setpos(0, 2);

				board.PrintBoard();
				_oper._pause_cls(50, 37);
			}

			else
			{
				cout << "怎么可能?" << endl;
				perror("_diff erroe");
			}

			_oper._cursor_invisible();
		}

		class AutoTimer {
		public:
			AutoTimer() : _start(chrono::high_resolution_clock::now()) {}

			// 返回经过的时间
			int elapsed() const {
				auto end = chrono::high_resolution_clock::now();
				return chrono::duration_cast<chrono::milliseconds>(end - _start).count();
			}

			// 重置计时器
			void reset() {
				_start = chrono::high_resolution_clock::now();
			}

		private:
			chrono::time_point<chrono::high_resolution_clock> _start;
		};






	private:
		int _diff;
		SystemOperation _oper;
		State _game_state;
	};

}

